﻿using System;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using AG.Infrastructure.Utility;
using VocabCards;
using Wnlib;

namespace WordNet.AG
{
    public class WordNetProxy
    {
        private static Wnlib.Opt[] wnlibOptions;
        private static readonly Wnlib.Opt _antonymOption;
        private static readonly Wnlib.Opt _synonymOption;

        static WordNetProxy()
        {
            var count = Wnlib.Opt.Count;

            wnlibOptions = new Wnlib.Opt[count];
            Enumerable.Range(0, count)
                .ToList()
                .ForEach(i =>
                         wnlibOptions[i] = Wnlib.Opt.at(i)
                );

            _antonymOption = wnlibOptions
                .Where(o => o.label.ToLower().Contains("antonym"))
                .ToList()
                .First();

            _synonymOption = wnlibOptions
                .Where(o => o.label.ToLower().Contains("synonym"))
                .First();
        }

        const string _dictpath = @"C:\Program Files\WordNet\2.1\dict\";

        WordProperties Overview(string word)
        {

            var wordNet = new WordNetClasses.WN(_dictpath);

            var list = new ArrayList();
            var b = false;
            Wnlib.SearchSet ss = null;

            wordNet.OverviewFor(word, "noun", ref b, ref ss, list);

            wordNet.OverviewFor(word, "verb", ref b, ref ss, list);

            wordNet.OverviewFor(word, "adj", ref b, ref ss, list);

            wordNet.OverviewFor(word, "adv", ref b, ref ss, list);

            var wProp = new WordProperties() { Word = word };

            //grouped by POS?
            foreach (var obj in list)
            {
                var result = (obj as Wnlib.Search);

                Wnlib.Search search = null;
                Opt antOption = null;
                Opt synOption = null;


                var i = 0;
                foreach (Wnlib.SynSet def in result.senses)
                {
                    search = new Wnlib.Search(word, false, result.pos, _synonymOption.sch, i + 1);

                    var synonyms = new List<string>();

                    foreach (var synonym in search.lexemes.Keys)
                        {
                            var val = synonym as Wnlib.Lexeme;
                            
                            if (!val.word.Equals(word, StringComparison.InvariantCultureIgnoreCase))
                                synonyms.Add(val.word.Replace("_", " "));
                        }

                    search = new Wnlib.Search(word, false, result.pos, _antonymOption.sch, i+1);
                    
                    var antonyms = new List<string>();
                    
                        foreach (var antonym in search.lexemes.Keys)
                        {
                            var val = antonym as Wnlib.Lexeme;
                            
                            if (! val.word.Equals(word, StringComparison.InvariantCultureIgnoreCase))
                                antonyms.Add(val.word.Replace("_", " "));
                        }
                    
                    var definition = new Definition()
                                         {
                                             PartOfSpeech = def.pos.name,
                                             Def = def.defn,
                                             Synonyms = synonyms,
                                             Antonyms = antonyms
                                         };

                    wProp.Definitions.Add(definition);


                    i++;
                }
            }

            return wProp;
        }


        public List<WordProperties> Define(IEnumerable<string> words)
        {
            if (words.Count() == 0)
            {
                return new WordProperties[0].ToList();
            }

            var wordProperties = new List<WordProperties>();

            words.ForEach<string>(
                w => wordProperties.Add(Overview(w.Trim())));

            return wordProperties;

        }


    }
}
